<script lang="jsx">
import { debounce } from "/@/utils";
import { message } from 'ant-design-vue';

const FILE_STATUS = {
  ready: undefined, // 文件准备就绪，从 window 文件选择器中选择完毕
  success: 'done', // 上传接口成功（仅代表 http 请求状态是成功的，真正的失败逻辑还得结合后端返回的状态码进行判断）
  fail: 'error', // 上传接口失败
  uploading: 'uploading', // 正在上传
  removed: 'removed', // 删除的
}
export default {
  name: "zeng-upload",
  // props 参考 https://www.antdv.com/components/upload-cn/#API
  props: {
    accept: {
      type: String,
      default: '.xlsx,.xls'
    },
    maxSize: Number, // 大小限制
    limit: Number, // 数量限制
    autoUpload: {
      type: Boolean,
      default: false
    },
    onChangeBefore: Function
    // 当只需要上传一个文件的时候，可以选择是在当前 fileList 中追加还是覆盖，比如上传头像的场景
  },
  data () {
    return {
      fileList: [],
    }
  },
  methods: {
    onChange: debounce(function ({ file, fileList }) {
      this.fileList = fileList
      if (this.onChangeBefore?.(file, fileList) === false) {
        // 自定义 change，并且返回 false 的话，就不往下执行
        return
      }
      if (this.clearReadyFileByLimit(fileList)) {
        this.$listeners.change?.(file, fileList)
      }
    }, 300, true),
    /**
     * 根据限制，清除不合法的文件
     * @param {Array} fileList 文件列表
     * @return {boolean} true
     */
    clearReadyFileByLimit (fileList) {
      let valid = true
      let deleteCount = 0
      for (let i = 0, len = fileList.length; i < len; i++) {
        const index = i - deleteCount
        const file = fileList[index]
        if ([FILE_STATUS.ready, FILE_STATUS.uploading].includes(file.status) && !this.checkFileLimit(file)) {
          valid = false
          deleteCount++
          fileList.splice(index, 1)
        }
      }
      if (typeof this.limit === 'number' && !this.checkFileLimitByLimit(fileList.length)) {
        fileList.splice(this.limit, fileList.length)
        message.error(`最多上传 ${this.limit} 个文件`)
        return false
      }
      return valid
    },
    /**
     * 检查文件的限制
     * @param file
     * @return {boolean}
     */
    checkFileLimit (file) {
      if (!this.checkFileLimitBySuffix(file.name.split('.')[1])) {
        message.error('文件类型不支持上传')
        return false
      }
      if (!this.checkFileLimitBySize(file.size)) {
        message.error(`文件大小不能超过 ${this.maxSize} MB！`);
        return false
      }
      return true
    },
    checkFileLimitBySuffix (suffix) {
      return this.accept ? this.accept.includes(suffix) : true
    },
    checkFileLimitBySize (size) {
      return typeof this.maxSize === 'number' ? size / 1024 / 1024 < this.maxSize : true
    },
    checkFileLimitByLimit (count) {
      return count <= this.limit
    }
  },
  computed: {
    antdUpload () {
      return this.$refs.antdUpload
    }
  },
  render () {
    return (
        <AUpload
            ref='antdUpload'
            id="upload-btn"
            beforeUpload={() => this.autoUpload}
            {...this.$attrs}
            accept={this.accept}
            file-list={this.fileList}
            onChange={this.onChange}
        >
          {this.$slots.default ?? <AButton>点击上传</AButton>}
        </AUpload>
    )
  },
}
</script>
